<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>FLIP 动画</title>
  <style>
    #container {
      margin: 0 auto;
      width: 500px;
      display: flex;
      flex-wrap: wrap;
    }
    .item {
      width: 100px;
      height: 100px;
      background-color: #004ff8;
      box-sizing: border-box;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 40px;
      color: #FFF;
      border: 1px solid #FFF;
    }
    .item:nth-child(2n) {
      background-color: #69B1FF;
    }
  </style>
</head>
<body>
  <div id="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
    <div class="item">4</div>
    <div class="item">5</div>
    <div class="item">6</div>
    <div class="item">7</div>
    <div class="item">8</div>
    <div class="item">9</div>
    <div class="item">10</div>
  </div>
  <button id="sort">随机排序</button>
</body>
<script>
const container = document.getElementById('container')
const sortBtn = document.getElementById('sort')

// 记录开始位置信息
function record(container) {
  const all = [...container.children]
  all.forEach((item, i) => {
    const rect = item.getBoundingClientRect()
    item.startX = rect.left
    item.startY = rect.top
    item.bgColor = getComputedStyle(item)['backgroundColor']
  })
}

function play(container) {
  const all = [...container.children]
  const len = all.length
  all.forEach((item, i) => {
    const rect = item.getBoundingClientRect()
    const currentX = rect.left
    const currentY = rect.top
    const bgColor = getComputedStyle(item, false)["backgroundColor"]
    item.animate([
      { transform: `translate(${item.startX - currentX}px, ${item.startY - currentY}px)`, backgroundColor: item.bgColor },
      { transform: 'translate(0px, 0px)', backgroundColor: bgColor }
    ], {duration: 600})
  })
}

function change() {
  const all = [...container.children]
  const len = all.length
  all.forEach((item, i) => {
    const newIndex = Math.floor(Math.random() * len)
    if (newIndex !== i) {
      const nextDOM = item.nextElementSibling
      container.insertBefore(item, all[newIndex])
      container.insertBefore(all[newIndex], nextDOM)
    }
  })
}

sortBtn.onclick = () => {
  record(container)
  change()
  play(container)
}
</script>
</html>
